home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / language / harvest.cpt / Harvest C / CHarvestApp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-16  |  18.6 KB  |  766 lines

  1. /*
  2.     Harvest C
  3.     Copyright 1992 Eric W. Sink.  All rights reserved.
  4.     
  5.     This file is part of Harvest C.
  6.     
  7.     Harvest C is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU Generic Public License as published by
  9.     the Free Software Foundation; either version 2, or (at your option)
  10.     any later version.
  11.     
  12.     Harvest C is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.     
  17.     You should have received a copy of the GNU General Public License
  18.     along with Harvest C; see the file COPYING.  If not, write to
  19.     the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20.     
  21.     Harvest C is not in any way a product of the Free Software Foundation.
  22.     Harvest C is not GNU software.
  23.     Harvest C is not public domain.
  24.  
  25.     This file may have other copyrights which are applicable as well.
  26.  
  27. */
  28.  
  29. /*****
  30.  * CHarvestApp.c
  31.  *
  32.  *    Application methods for Harvest C
  33.  *
  34.  *  Copyright ⌐ 1990 Symantec Corporation.  All rights reserved.
  35.  *
  36.  *****/
  37.  
  38. #include "CHarvestApp.h"
  39. #include "CHarvestDoc.h"
  40. #include "CDLOGDialog.h"
  41. #include "CDialogText.h"
  42. #include "CTclShell.h"
  43. #include "CDLOGDirector.h"
  44. #include "CAppleEvent.h"
  45. #include "CBartender.h"
  46. #include "Commands.h"
  47. #include "HarvestCommands.h"
  48. #include "CSourceFile.h"
  49. #include "CDataFile.h"
  50. #include "CList.h"
  51. #include "Global.h"
  52. #include <AppleEvents.h>
  53. #include <TBUtilities.h>
  54.  
  55. extern    OSType    gSignature;
  56. extern  CBartender *gBartender;
  57. extern  CDesktop *gDesktop;
  58. extern  CHarvestApp *gApplication;
  59. extern    CHarvestDoc *gProject;
  60. extern CursHandle    gIBeamCursor;        /* I-beam for text views            */
  61. extern CursHandle    gWatchCursor;        /* Watch cursor for waiting            */
  62. extern CBureaucrat    *gGopher;            /* First in line to get commands    */
  63. extern CTclShell *gShell;
  64.  
  65. pascal OSErr
  66. AEDoScriptHandler(AppleEvent *message,AppleEvent *reply,long refnum);
  67.  
  68. Str255 MyVersion;
  69. extern int app_refnum;
  70. extern int xtcl_refnum;
  71.  
  72.  
  73. #define        kExtraMasters        4
  74. #define        kRainyDayFund        20480
  75. #define        kCriticalBalance    20480
  76. #define        kToolboxBalance        20480
  77.  
  78.  
  79. OSErr
  80. FindSystemHeaders(short vRefNum,long dirID,char *name,FSSpec *buf)
  81. {
  82.     OSErr result;
  83.     short vnum;
  84.     long id;
  85.     CInfoPBRec spec1;
  86.     CInfoPBRec spec2;
  87.     HParamBlockRec pb;
  88.     Str255 pname;
  89.     strcpy((char *) pname,name);
  90.     c2pstr(pname);
  91.     
  92.     HGetVol(NULL,&vnum,&id);
  93.     
  94.     spec1.hFileInfo.ioNamePtr = pname;
  95.     spec1.hFileInfo.ioFlAttrib = 0x10;
  96.     spec2.hFileInfo.ioNamePtr = NULL;
  97.     spec2.hFileInfo.ioFlAttrib = 0x10;
  98.     pb.csParam.ioNamePtr = NULL;
  99.     pb.csParam.ioCompletion = NULL;
  100.     pb.csParam.ioSearchBits = fsSBFullName + fsSBFlAttrib;
  101.     pb.csParam.ioSearchInfo1 = &spec1;
  102.     pb.csParam.ioSearchInfo2 = &spec2;
  103.     pb.csParam.ioSearchTime = -1;
  104.     pb.csParam.ioCatPosition.initialize = 0;
  105.     pb.csParam.ioOptBuffer = NULL;
  106.     pb.csParam.ioOptBufSize = 0;
  107.     pb.csParam.ioVRefNum = vnum;
  108.     pb.csParam.ioMatchPtr = buf;
  109.     pb.csParam.ioReqMatchCount = 1;
  110.     
  111.     result = PBCatSearchSync(&pb);
  112.     if (!pb.csParam.ioActMatchCount) return -43;
  113.     return result;
  114. }
  115.  
  116. void CHarvestApp::IHarvestApp(void)
  117.  
  118. {
  119.     CApplication::IApplication( kExtraMasters, kRainyDayFund, 
  120.                         kCriticalBalance, kToolboxBalance);
  121.     
  122.  
  123. /*  The parameters to IApplication are the number of times to call  
  124.     MoreMasters, the total number of bytes of heap space to reserve for                       
  125.     monitoring low memory situations, and the portion of the memory
  126.     reserve to set aside for critical operations and toolbox calls.
  127.     
  128.     Four (4) is a reasonable number of MoreMasters calls,                           
  129.     but you should determine a good number for your application                     
  130.     by observing the heap using Lightsbug,                                              
  131.     TMON, or Macsbug. Set this parameter to zero, give your                         
  132.     program a rigorous work-out, then look at the heap and count                        
  133.     how many master pointer blocks have been allocated. Master                      
  134.     pointer blocks are nonrelocatable and have a size of $100                           
  135.     (hex). You should call MoreMasters at least this many                               
  136.     times -- add a few extra just to be safe. The purpose of all                        
  137.     this preflighting is to prevent heap fragmentation. You                             
  138.     don't want the Memory Manager to call MoreMasters and                           
  139.     create a nonrelocatable block in the middle of your heap. By                        
  140.     calling MoreMasters at the very beginning of the program,                           
  141.     you ensure that these blocks are allocated in a group at the                        
  142.     bottom of the heap. 
  143.                                                                         
  144.     The memory reserve is a safeguard for handling low memory                   
  145.     conditions and is used by the GrowMemory method in                              
  146.     CApplication (check there for more comments). In general,                           
  147.     your program should never request a memory block greater                        
  148.     than this reserve size without explicitly checking in                               
  149.     advance whether there is enough free memory to satisfy the                      
  150.     the request.
  151.                                                                                     
  152.  */
  153.      Init(0,NULL);
  154.      
  155.      BeachBalls[0] = GetCursor(500);
  156.      FailNILRes(BeachBalls[0]);
  157.     HNoPurge( (Handle) BeachBalls[0]);
  158.     
  159.      BeachBalls[1] = GetCursor(501);
  160.      FailNILRes(BeachBalls[1]);
  161.     HNoPurge( (Handle) BeachBalls[1]);
  162.     
  163.      BeachBalls[2] = GetCursor(502);
  164.      FailNILRes(BeachBalls[2]);
  165.     HNoPurge( (Handle) BeachBalls[2]);
  166.     
  167.      BeachBalls[3] = GetCursor(503);
  168.      FailNILRes(BeachBalls[3]);
  169.     HNoPurge( (Handle) BeachBalls[3]);
  170.     
  171.     BeachIndex = 0;
  172.  
  173.     app_refnum = xtcl_refnum = CurResFile();
  174.     
  175.     {
  176.         FSSpec spec;
  177.  
  178.         FCBPBRec fcbpb;
  179.         OSErr err;
  180.         fcbpb.ioNamePtr = (void *) HarvestCTree.name;
  181.         fcbpb.ioVRefNum = 0;
  182.         fcbpb.ioRefNum = CurResFile();
  183.         fcbpb.ioFCBIndx = 0;
  184.         err = PBGetFCBInfoSync(&fcbpb);
  185.         HarvestCTree.vRefNum = fcbpb.ioVRefNum;
  186.         HarvestCTree.parID = fcbpb.ioFCBParID;
  187.         
  188.         set_current_wd(HarvestCTree.vRefNum,HarvestCTree.parID);
  189.  
  190.         {
  191.             CInfoPBRec cfb;
  192.             Str255 tempPath;
  193.             CopyPString("\p(Harvest C Headers)",tempPath);
  194.             cfb.hFileInfo.ioNamePtr = tempPath;
  195.             cfb.hFileInfo.ioDirID = HarvestCTree.parID;
  196.             cfb.hFileInfo.ioVRefNum = HarvestCTree.vRefNum;
  197.             cfb.hFileInfo.ioFDirIndex = 0;
  198.             err = PBGetCatInfoSync(&cfb);
  199.             if (!err) {
  200.                 StdIncludeDir = cfb.hFileInfo.ioDirID;
  201.                 StdIncludeVol = cfb.hFileInfo.ioVRefNum;
  202.             }
  203.             else {
  204.                 StdIncludeDir = 0;
  205.                 StdIncludeVol = 0;
  206.             }
  207.         }
  208.  
  209.         {
  210.             CInfoPBRec cfb;
  211.             Str255 tempPath;
  212.             CopyPString("\p(Harvest C Libraries)",tempPath);
  213.             cfb.hFileInfo.ioNamePtr = tempPath;
  214.             cfb.hFileInfo.ioDirID = HarvestCTree.parID;
  215.             cfb.hFileInfo.ioVRefNum = HarvestCTree.vRefNum;
  216.             cfb.hFileInfo.ioFDirIndex = 0;
  217.             err = PBGetCatInfoSync(&cfb);
  218.             if (!err) {
  219.                 StdLibDir = cfb.hFileInfo.ioDirID;
  220.                 StdLibVol = cfb.hFileInfo.ioVRefNum;
  221.             }
  222.             else {
  223.                 StdLibDir = 0;
  224.                 StdLibVol = 0;
  225.             }
  226.         }
  227.     }
  228.     {
  229.         VersRecHndl v;
  230.         v = (VersRecHndl) Get1Resource('vers',1);
  231.         if (v) {
  232.             CopyPString((*v)->shortVersion,MyVersion);
  233.         }
  234.         else {
  235.             CopyPString("\pVersion???",MyVersion);
  236.         }
  237.     }
  238. }
  239.  
  240. void CHarvestApp::DoAppleEvent( CAppleEvent *anAppleEvent)
  241. {
  242.     DescType    eventClass;
  243.     DescType    eventID;
  244.     OSErr        err;
  245.     
  246.     eventClass = anAppleEvent->GetEventClass();
  247.     eventID = anAppleEvent->GetEventID();
  248.     
  249.     if (eventClass == kCoreEventClass)
  250.     {
  251.         switch (eventID)
  252.         {
  253.             case kAEOpenApplication:
  254.                     if (anAppleEvent->GotRequiredParams())
  255.                     {
  256.                         anAppleEvent->SetErrorResult( noErr);
  257.                     }
  258.                     break;
  259.                     
  260.             case kAEOpenDocuments:
  261.                     DoOpenOrPrintDocEvent( anAppleEvent);
  262.                     break;
  263.                     
  264.             case kAEPrintDocuments:
  265.                     err = anAppleEvent->RequestInteraction( MAXLONG);
  266.                     if (err == noErr)
  267.                     {
  268.                         DoOpenOrPrintDocEvent( anAppleEvent);
  269.                     }
  270.                     else
  271.                         anAppleEvent->SetErrorResult( err);
  272.                     break;
  273.                 
  274.             case kAEQuitApplication:
  275.             
  276.                     if (anAppleEvent->GotRequiredParams())
  277.                     {
  278.                         err = anAppleEvent->RequestInteraction( MAXLONG);
  279.                         if (err == noErr)
  280.                         {
  281.                             Quit();
  282.                         
  283.                         }
  284.                         anAppleEvent->SetErrorResult( err);
  285.                     }
  286.                     break;
  287.         }        
  288.     }
  289.     else if (eventClass == 'misc') {
  290.         AppleEvent mesg;
  291.         switch (eventID) {
  292.             case 'dosc':
  293.                 mesg = anAppleEvent->GetAEEvent();
  294.                 AEDoScriptHandler(&mesg,NULL,0);        
  295.                 break;
  296.         }
  297.     }
  298. }
  299.  
  300. void    CHarvestApp::StartUpAction(
  301.     short    numPreloads)
  302. {
  303.     FlushEvents(everyEvent, 0);
  304.     
  305.     if (!gSystem.hasAppleEvents && (numPreloads == 0))
  306.     {
  307.         gGopher->DoCommand(cmdAbout);
  308.     }
  309. }
  310.  
  311.  
  312. void CHarvestApp::SetUpFileParameters(void)
  313.  
  314. {
  315.     inherited::SetUpFileParameters();    /* Be sure to call the default method */
  316.  
  317.         /**
  318.          **    sfNumTypes is the number of file types
  319.          **    your application knows about.
  320.          **    sfFileTypes[] is an array of file types.
  321.          **    You can define up to 4 file types in
  322.          **    sfFileTypes[].
  323.          **
  324.          **/
  325.  
  326.     sfNumTypes = 3;
  327.     sfFileTypes[0] = 'Hprj';
  328.     sfFileTypes[1] = 'TEXT';
  329.     sfFileTypes[2] = 'OBJ ';
  330.  
  331.     gSignature = 'Jn15';
  332. }
  333.  
  334.  
  335. void CHarvestApp::SetUpMenus()
  336.  {
  337.  
  338.   inherited::SetUpMenus();  /*  Superclass takes care of adding     
  339.                                 menus specified in a MBAR id = 1    
  340.                                 resource    
  341.                             */                          
  342.  
  343.         /* Add your code for creating run-time menus here */    
  344.  }
  345.  
  346.  
  347. /*
  348.  * Handle selection of About item from Apple menu
  349.  */
  350.  
  351. void CHarvestApp::DoAbout(void)
  352. {
  353.     CDLOGDirector *dialog;
  354.     CDialogText *version;
  355.     
  356.     dialog = new CDLOGDirector;    
  357.     dialog->IDLOGDirector( 130, this);
  358.     dialog->BeginDialog();
  359.     version = (CDialogText *) dialog->itsWindow->FindViewByID(3);
  360.     if (version) {
  361.         version->Deactivate();
  362.         version->SetFontNumber(geneva);
  363.         version->SetTextString(MyVersion);
  364.     }
  365.         
  366.     dialog->DoModalDialog( cmdOK);
  367.     ForgetObject(dialog);
  368. }
  369.  
  370. /*
  371.  * Handle selection of Registration... item from Apple menu
  372.  */
  373.  
  374. void CHarvestApp::DoRegistration(void)
  375. {
  376.     CDLOGDirector *dialog;
  377.     
  378.         dialog = new CDLOGDirector;    
  379.         dialog->IDLOGDirector( 230, this);
  380.         dialog->BeginDialog();
  381.             
  382.         dialog->DoModalDialog( cmdOK);
  383.         ForgetObject(dialog);
  384. }
  385.  
  386. void    CHarvestApp::ChooseProjectFile(
  387.     SFReply        *macSFReply)
  388. {
  389.     Point        corner;                    /* Top left corner of dialog box    */
  390.     Boolean        wasLocked;
  391.     SFTypeList    oneType;
  392.                                         /* Center dialog box on the screen    */
  393.     FindDlogPosition('DLOG', sfGetDLOGid, &corner);
  394.     
  395.     wasLocked = Lock( TRUE);
  396.     
  397.     oneType[0] = 'Hprj';
  398.     SFPGetFile(corner, "\p", sfFileFilter, 1, oneType,
  399.                 sfGetDLOGHook, macSFReply, sfGetDLOGid, sfGetDLOGFilter);
  400.                 
  401.     Lock( wasLocked);
  402. }
  403.  
  404. Boolean SamePStrings(char *a,char *b)
  405. {
  406.     int c;
  407.     c = *a;
  408.     while (c--) {
  409.         if (*a != *b) return FALSE;
  410.         a++;b++;
  411.     }
  412.     return TRUE;
  413. }
  414.  
  415. pascal Boolean SourceFileFilter(FileParam * p)
  416. {
  417.     int len;
  418.     int CountSourceFiles;
  419.     int i;
  420.     CSourceFile *aFile;
  421.     /* Now check if it's in the project already. */
  422.     CountSourceFiles = gProject->itsSourceFiles->GetNumItems();
  423.     for (i=1;i<=CountSourceFiles;i++) {
  424.         aFile = (CSourceFile *) gProject->itsSourceFiles->NthItem(i);
  425.         if (SamePStrings((char *) p->ioNamePtr,(char *) aFile->theFile->name)) {
  426.             return TRUE;
  427.         }
  428.     }
  429.     if (p->ioFlFndrInfo.fdType == 'TEXT') {
  430.         len = p->ioNamePtr[0];    /* assume pascal string, of course */
  431.         if (p->ioNamePtr[len] == 'c') {
  432.             if (p->ioNamePtr[len-1] == '.') {
  433.                 return FALSE;
  434.             }
  435.         }
  436.     }
  437.     else if (p->ioFlFndrInfo.fdType == 'OBJ ') {
  438.         return FALSE;
  439.     }
  440.     else if (p->ioFlFndrInfo.fdCreator == 'RSED') {
  441.         return FALSE;
  442.     }
  443.     else if (p->ioFlFndrInfo.fdType == 'rsrc') {
  444.         return FALSE;
  445.     }
  446.     return TRUE;
  447. }
  448.  
  449. void    CHarvestApp::ChooseSourceFile(
  450.     SFReply        *macSFReply)
  451. {
  452.     Point        corner;                    /* Top left corner of dialog box    */
  453.     Boolean        wasLocked;
  454.     SFTypeList    oneType;
  455.                                         /* Center dialog box on the screen    */
  456.     FindDlogPosition('DLOG', sfGetDLOGid, &corner);
  457.     
  458.     wasLocked = Lock( TRUE);
  459.     
  460.     oneType[0] = 'TEXT';
  461.     SFPGetFile(corner, "\p", (FileFilterProcPtr) SourceFileFilter, -1, oneType,
  462.                 sfGetDLOGHook, macSFReply, sfGetDLOGid, sfGetDLOGFilter);
  463.                 
  464.     Lock( wasLocked);
  465. }
  466.  
  467. void    CHarvestApp::ChooseLibFile(
  468.     SFReply        *macSFReply)
  469. {
  470.     Point        corner;                    /* Top left corner of dialog box    */
  471.     Boolean        wasLocked;
  472.     SFTypeList    oneType;
  473.                                         /* Center dialog box on the screen    */
  474.     FindDlogPosition('DLOG', sfGetDLOGid, &corner);
  475.     
  476.     wasLocked = Lock( TRUE);
  477.     
  478.     oneType[0] = 'OBJ ';
  479.     SFPGetFile(corner, "\p", sfFileFilter, 1, oneType,
  480.                 sfGetDLOGHook, macSFReply, sfGetDLOGid, sfGetDLOGFilter);
  481.                 
  482.     Lock( wasLocked);
  483. }
  484.  
  485. void
  486. DoOpenProject(void)
  487. {
  488.     SFReply macSFReply;
  489.     gApplication->ChooseProjectFile(&macSFReply);
  490.     if (macSFReply.good) {
  491.         SetCursor(*gWatchCursor);
  492.         gApplication->OpenProject(&macSFReply);
  493.     }
  494. }
  495.  
  496. void CHarvestApp::DoCommand(long theCommand)
  497. {
  498.     SFReply macSFReply;
  499.     int oldNumTypes;
  500.     switch (theCommand) {
  501.     
  502.         case cmdAbout:
  503.             DoAbout();
  504.             break;
  505.         case cmdRegistration:
  506.             DoRegistration();
  507.             break;
  508.         case cmdNewProject:
  509.         case cmdNew:
  510.                 SetCursor(*gWatchCursor);
  511.             CreateProject();
  512.         break;
  513.         case cmdOpenProject:
  514.         case cmdOpen:
  515.                 DoOpenProject();
  516.         break;
  517.         case cmdDebugger:
  518.             Debugger();
  519.             break;
  520.         case cmdSwitchToAlpha:
  521.             {
  522.                 ProcessSerialNumber process;
  523.                 ProcessInfoRec InfoRec;
  524.                 FSSpec theSpec;
  525.                 if (FindAProcess('ALFA',&process,&InfoRec,&theSpec)) {
  526.                     SetFrontProcess(&process);
  527.                 }
  528.                     /* Maybe later, locate the appl using the desktop manager,
  529.                         and launch it. */
  530.             }
  531.             break;
  532.         case cmdTclShell:
  533.             {
  534.                 /* Open a Tcl shell */
  535.                 CTclShell    *theShell = NULL;
  536.                                 
  537.                 TRY
  538.                 {
  539.                     gShell = theShell = new(CTclShell);
  540.                         
  541.                     theShell->ITclShell(this, TRUE);
  542.                 
  543.                     theShell->NewFile();
  544.                 }
  545.                 CATCH
  546.                 {
  547.                     ForgetObject( theShell);
  548.                 }
  549.                 ENDTRY;
  550.             };
  551.             break;
  552.         default:    inherited::DoCommand(theCommand);
  553.                     break;
  554.     }
  555. }
  556.  
  557.  
  558.  void CHarvestApp::UpdateMenus()
  559.  {
  560.   inherited::UpdateMenus();     /* Enable standard commands */ 
  561.   gBartender->SetDimOption(MENUproject,dimNONE);     
  562.   gBartender->SetDimOption(MENUsources,dimALL);
  563.   gBartender->EnableCmd(cmdTclShell);
  564.   gBartender->EnableCmd(cmdSwitchToAlpha);
  565.   gBartender->EnableCmd(cmdDebugger);
  566.   gBartender->EnableCmd(cmdNewProject);
  567.   gBartender->EnableCmd(cmdOpenProject);
  568.   gBartender->DisableCmd(cmdPageSetup);   
  569.   gBartender->EnableCmd(cmdNew);   
  570.   gBartender->EnableCmd(cmdOpen);
  571.    
  572.   gBartender->DisableCmd(cmdSave);   
  573.   gBartender->DisableCmd(cmdSaveAs);
  574.      
  575.   gBartender->DisableCmd(cmdCloseProject);   
  576.   gBartender->DisableCmd(cmdClose);  
  577.    
  578.   gBartender->DisableCmd(cmdOptions);
  579.   gBartender->DisableCmd(cmdWarnings);
  580.   gBartender->DisableCmd(cmdSetProjectInfo);   
  581.   gBartender->DisableCmd(cmdClean);   
  582.   gBartender->DisableCmd(cmdBringUpToDate);   
  583.   gBartender->DisableCmd(cmdBuildApplication);   
  584.   gBartender->DisableCmd(cmdCheckLink);   
  585.   gBartender->DisableCmd(cmdRun);   
  586.  
  587.     /* Enable the commands handled by your Application class */ 
  588.  }
  589.  
  590.  
  591. void CHarvestApp::Exit()
  592.  
  593. {
  594.     /* your exit handler here */
  595. }
  596.  
  597.  
  598. void CHarvestApp::CreateProject()
  599.  
  600. {
  601.     CHarvestDoc *newDocument;
  602.     newDocument = new(CHarvestDoc);
  603.     newDocument->IHarvestDoc(this,false);
  604.     newDocument->NewFile();
  605. }
  606.  
  607. void CHarvestApp::CreateDocument()
  608.  
  609. {
  610.     CHarvestDoc *newDocument;
  611.     newDocument = new(CHarvestDoc);
  612.     newDocument->IHarvestDoc(this,false);
  613.     newDocument->NewFile();
  614. }
  615.  
  616. void CHarvestApp::OpenDocument(SFReply *macSFReply)
  617.  
  618. {
  619.     CHarvestDoc    *theDocument = NULL;
  620.     
  621.     TRY
  622.     {
  623.     
  624.         theDocument = new(CHarvestDoc);
  625.             
  626.             /**
  627.              **    Send your document an initialization
  628.              **    message. The first argument is the
  629.              **    supervisor (the application). The second
  630.              **    argument is TRUE if the document is printable.
  631.              **
  632.              **/
  633.         
  634.         theDocument->IHarvestDoc(this, false);
  635.     
  636.             /**
  637.              **    Send the document an OpenFile() message.
  638.              **    The document will open a window, open
  639.              **    the file specified in the macSFReply record,
  640.              **    and display it in its window.
  641.              **
  642.              **/
  643.         theDocument->OpenFile(macSFReply);
  644.     }
  645.     
  646.     CATCH
  647.     {
  648.         /*
  649.          * This exception handler gets executed if a failure occurred 
  650.          * anywhere within the scope of the TRY block above. Since 
  651.          * this indicates that the document could not be opened, we
  652.          * send it a Dispose message. The exception will propagate up to
  653.          * CSwitchboard's exception handler, which handles displaying
  654.          * an error alert.
  655.          */
  656.          
  657.          if (theDocument) theDocument->Dispose();
  658.     }
  659.     ENDTRY;
  660. }
  661.  
  662. void CHarvestApp::OpenProject(SFReply *macSFReply)
  663.  
  664. {
  665.     CHarvestDoc    *theDocument = NULL;
  666.     
  667.     TRY
  668.     {
  669.     
  670.         theDocument = new(CHarvestDoc);
  671.             
  672.             /**
  673.              **    Send your document an initialization
  674.              **    message. The first argument is the
  675.              **    supervisor (the application). The second
  676.              **    argument is TRUE if the document is printable.
  677.              **
  678.              **/
  679.         
  680.         theDocument->IHarvestDoc(this, false);
  681.     
  682.             /**
  683.              **    Send the document an OpenFile() message.
  684.              **    The document will open a window, open
  685.              **    the file specified in the macSFReply record,
  686.              **    and display it in its window.
  687.              **
  688.              **/
  689.         theDocument->OpenFile(macSFReply);
  690.     }
  691.     
  692.     CATCH
  693.     {
  694.         /*
  695.          * This exception handler gets executed if a failure occurred 
  696.          * anywhere within the scope of the TRY block above. Since 
  697.          * this indicates that the document could not be opened, we
  698.          * send it a Dispose message. The exception will propagate up to
  699.          * CSwitchboard's exception handler, which handles displaying
  700.          * an error alert.
  701.          */
  702.          
  703.          if (theDocument) theDocument->Dispose();
  704.     }
  705.     ENDTRY;
  706. }
  707.  
  708. OSErr
  709. FindOMFFile(char *name,short volrefnum, long dirID, FSSpec *f)
  710. {
  711.   FInfo junk;
  712.   OSErr bad;
  713.   Str255 pname;
  714.  
  715.   strcpy(f->name,name);
  716.   strcpy(pname,name);
  717.   c2pstr(pname);
  718.   
  719.   /* Search path : current app dir, lib dir, etc... */
  720.   
  721.   bad = HGetFInfo(f->vRefNum = volrefnum, f->parID = dirID,pname,&junk);
  722.   if (!bad) return bad;
  723.  
  724.   bad = HGetFInfo(f->vRefNum = gProject->StdAppVol, f->parID = gProject->StdAppDir,pname,&junk);
  725.   if (!bad) return bad;
  726.  
  727.   bad = HGetFInfo(f->vRefNum = gApplication->StdLibVol, f->parID = gApplication->StdLibDir,pname,&junk);
  728.   if (!bad) return bad;
  729.   
  730.   return bad;
  731. }
  732.  
  733. OSErr
  734. FindCFile(char *name,short volrefnum, long dirID, FSSpec *f)
  735. {
  736.   FInfo junk;
  737.   OSErr bad;
  738.   Str255 pname;
  739.  
  740.   strcpy(f->name,name);
  741.   strcpy(pname,name);
  742.   c2pstr(pname);
  743.   
  744.   /* Search path : current app dir, lib dir, etc... */
  745.   
  746.   bad = HGetFInfo(f->vRefNum = volrefnum, f->parID = dirID,pname,&junk);
  747.   if (!bad) return bad;
  748.  
  749.   bad = HGetFInfo(f->vRefNum = gProject->StdAppVol, f->parID = gProject->StdAppDir,pname,&junk);
  750.   if (!bad) return bad;
  751.  
  752.   bad = HGetFInfo(f->vRefNum = gApplication->StdLibVol, f->parID = gApplication->StdLibDir,pname,&junk);
  753.   if (!bad) return bad;
  754.   
  755.   return bad;
  756. }
  757.  
  758. void CHarvestApp::SpinCursor(void)
  759. {
  760.     EventRecord junk;
  761.     BeachIndex = (BeachIndex + 1) % 4;
  762.     SetCursor(*(BeachBalls[BeachIndex]));
  763.     WaitNextEvent(0,&junk,0,NULL);
  764. }
  765.  
  766.